﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using MvcContrib.Interfaces;
using MvcContrib.UI;
using MvcContrib.Services;

namespace JqueryMvc.Attributes
{
    public class AjaxControllerAttribute: System.Web.Mvc.ActionFilterAttribute, IExceptionFilter
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
            ViewResult result = filterContext.Result as ViewResult;

			if (result == null)
                return;

			if (filterContext.HttpContext.Request.IsAjaxRequest())
			{
				if (filterContext.HttpContext.Request.GetPreferedResponseType() == ResponseType.Html)
				{
					//load partial, only webformviewengine is supported now
					//if (result.ViewEngine is WebFormViewEngine)
					//	((WebFormViewEngine)result.ViewEngine).ViewLocator = DependencyResolver.GetImplementationOf<ComponentViewLocator>();
                    if (filterContext.Result is ViewResult)
                    {
                        string viewName = ((ViewResult)filterContext.Result).ViewName;
                        if (String.IsNullOrEmpty(viewName))
                            viewName = filterContext.RouteData.GetRequiredString("action");
                        ((ViewResult)filterContext.Result).ViewName = "_" + viewName;
                    }
				}
				else if (filterContext.HttpContext.Request.GetPreferedResponseType() == ResponseType.Json)
				{
					ViewDataDictionary data = ((ViewResult)filterContext.Result).ViewData;
					object model = data;
					if (data.Model is Exception)
						model = data.Model;
					if (filterContext.Exception != null)
						model = filterContext.Exception;

					if (model is Exception)
					{
						Exception exc = ((Exception)model).InnerException;
						if (exc is HttpException)
						{
							filterContext.HttpContext.Response.StatusCode = ((HttpException)exc).GetHttpCode();
						}
						else
						{
							filterContext.HttpContext.Response.StatusCode = 500;
						}
						filterContext.HttpContext.Response.StatusDescription = exc.Message;

						model = exc;
					}

					filterContext.Result = new JsonResult()
					{
						Data = model
					};
				}
			}
        }

		public void OnException(ExceptionContext filterContext)
        {
			if (filterContext.HttpContext.Request.GetPreferedResponseType() == ResponseType.Json)
			{
				filterContext.Result = new JsonResult()
				{
					Data = new {errors = new SimpleException[] {new SimpleException(filterContext.Exception)}}
				};
				filterContext.HttpContext.Response.Clear();
				filterContext.ExceptionHandled = true;
				if (filterContext.Exception is HttpException)
				{
					filterContext.HttpContext.Response.StatusCode = ((HttpException)filterContext.Exception).GetHttpCode();
				}
				else
				{
					filterContext.HttpContext.Response.StatusCode = 500;
				}
				filterContext.HttpContext.Response.StatusDescription = filterContext.Exception.Message;
			}
        }

	}
}
